﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using TowerDef_s_enseLibrary.enemy;

namespace TowerDef_s_enseLibrary.tower.spiketower
{
    class SpikeTower : Tower
    {
        #region variables

        // A list of directions that the tower can shoot in
        private readonly Vector2[] _directions = new Vector2[8];
        // All the enimes that are in range of the tower
        private List<Enemy> _targets = new List<Enemy>();

        /// <summary>
        /// Spike tower will never have just one target
        /// </summary>
        public override bool HasTarget
        {
            get
            {
                return false;
            }
        }

        #endregion variables

        #region functions

        /// <summary>
        /// Create a spike tower
        /// </summary>
        /// <param name="texture">The spike tower Texture</param>
        /// <param name="bulletTexture">The bullet Texture</param>
        /// <param name="position">The tower position</param>
        public SpikeTower(Texture2D texture, Texture2D bulletTexture, Vector2 position) : base(texture, bulletTexture, position)
        {
            this.damage = 20;
            this.cost = 40;
            this.radius = 48;

            // Store a list of all the directions the tower can shoot
            _directions = new Vector2[]
            {
               new Vector2(-1, -1), // North West
               new Vector2( 0, -1), // North
               new Vector2( 1, -1), // North East
               new Vector2(-1,  0), // West
               new Vector2( 1,  0), // East
               new Vector2(-1,  1), // South West
               new Vector2( 0,  1), // South
               new Vector2( 1,  1), // South East
            };
        }

        /// <summary>
        /// Get the closest Enemy
        /// </summary>
        /// <param name="enemies">The list of all _enemies</param>
        public override void GetClosestEnemy(List<Enemy> enemies)
        {
            // Do a fresh search for _targets
            _targets.Clear();

            // Loop over all the _enemies
            foreach(Enemy enemy in enemies)
            {
                // Check wether this enemy is in shooting distance.
                if(IsInRange(enemy.Center))
                {
                    // Make it a target.
                    _targets.Add(enemy);
                }
            }
        }

        /// <summary>
        /// Updates the spike tower in matters of the game time
        /// </summary>
        /// <param name="gameTime">The current game time</param>
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            bulletTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;

            // Decide if it is time to shoot
            if(bulletTimer >= 1.0f && _targets.Count != 0)
            {
                // For every direction the tower can shoot
                foreach (Vector2 dir in _directions)
                {
                    // create a new bullet that moves in that direction
                    var bullet = new Bullet(bulletTexture, Vector2.Subtract(center,
                        new Vector2(bulletTexture.Width / 2)), dir, 6, damage);
                    bulletList.Add(bullet);
                }

                bulletTimer = 0;
            }

            // Loop through all the bullets
            for(int i = 0; i < bulletList.Count; i++)
            {
                Bullet bullet = bulletList[i];
                bullet.Update(gameTime);

                // Kill the bullet when it is out of range
                if(!IsInRange(bullet.Center))
                {
                    bullet.Kill();
                }

                // Loop through all the possible _targets
                foreach (Enemy enemy in _targets)
                {
                    // If this bullet hits a target and is in range
                    if(enemy != null && Vector2.Distance(bullet.Center, enemy.Center) < 12)
                    {
                        // hurt the enemy
                        enemy.CurrentHealth -= bullet.Damage;
                        bullet.Kill();

                        // This bullet can't kill anyone else.
                        break;
                    }
                }

                // Remove the bullet if it is dead
                if(bullet.IsDead())
                {
                    bulletList.Remove(bullet);
                    i--;
                }
            }
        }

        #endregion functions

        #region events



        #endregion events
    }
}

